#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>

using std::cout;
using std::endl;
using std::vector;
using std::set;
using std::map;
using std::string;
using std::ifstream;
using std::istringstream;


class TextQuery
{
public:
    void readFile(const string & filename);
    void query(const string & word);

private:
    void preprocess(string & w);
private:
    //_file中存储的是每一行的内容
    vector<string> _file;
    //每个单词所在的行号, set中存储的是所有的行号
    map<string, set<int>> _wordNumbers;
    //每个单词出现的次数
    map<string, int> _dict;
};

void TextQuery::readFile(const string & filename)
{
    ifstream ifs(filename);
    if(!ifs.good()) {
        cout << "ifstream open file " << filename << " error" << endl;
        return ;
    }

    string line;
    string word;
    int cnt = 0;
    while(getline(ifs, line)) {
        //将每一行放到vector中
        _file.push_back(line);//下标0 代表的是第一行

        istringstream iss(line);
        while(iss >> word) {
            preprocess(word);
            ++_dict[word];//进行词频统计
            _wordNumbers[word].insert(cnt);
        }
        ++cnt;
    }

    ifs.close();
}
    
void TextQuery::query(const string & word)
{
    auto iter = _dict.find(word);
    if(iter == _dict.end()) {
        cout << word << " not found." << endl;
        return ;
    }
    //找到的情况
    cout << word << " occurs " << _dict[word] << " times." << endl;
    set<int> & lineNumbers = _wordNumbers[word];
    for(auto & no : lineNumbers) {
        cout << "(line " << no + 1 <<")" << _file[no] << endl;
    }
}

void TextQuery::preprocess(string & w)
{
    //如果发现其中有字符不是字母，就直接忽略掉该单词
    //如果发现其中有字符是大写字母，就改写小写字母
    for(int i = 0; i < w.size(); ++i) {
        if(!isalpha(w[i])) {
            w=string();
            break;
        }
        if(isupper(w[i])) {
            w[i] = tolower(w[i]);
        }
    }
}
int main()
{
    TextQuery tq;
    tq.readFile("1_WordStatistic.cc");
    tq.query("cout");

    return 0;
}

